#!/home/hadoop/anaconda2/bin
# -*- coding:utf-8 -*-
import json
import logging
import requests
import time

from .setting import *


class GavialApi(object):
  """
      gavial api model for get config from api server by http
  """

  def __init__(self, host, port):
    self._base_url = 'http://{0}:{1}'.format(host, port)

  def get_job_config(self, task_name, job_name, exec_id='-1'):
    if task_name is None or job_name is None:
      logging.error(
        'get_job_config [task_name:{0},job_name:{1}] error,params can not be none'
        .format(task_name, job_name))
      return None
    data = {'taskName': task_name, 'jobName': job_name, 'execId': exec_id}
    url = '{0}{1}'.format(self._base_url, URL_GET_JOB_CONF)
    r = requests.get(url=url, params=data, timeout=60)
    if r.status_code == requests.codes.ok:
      return r.json()
    else:
      logging.error('gavial api server return code:{0},msg:{1}'.format(
        r.status_code,
        str(r.content)))
      return None

  def save_job_runtime_config(self, task_name, job_name, exec_id,
      job_config):
    if task_name is None or exec_id is None or job_name is None or not isinstance(
        job_config, dict):
      logging.error(
        'save_job_runtime_config [task_name:{0},exec_id:{1},job_name:{2},job_config:{3}] error,params error'
        .format(task_name, exec_id, job_name, job_config))
      return None
    url = '{0}{1}?taskName={2}&jobName={3}&execId={4}'.format(
      self._base_url, URL_SAVE_JOB_RUNTIME_CONF, task_name, job_name,
      exec_id)
    headers = {'Content-type': 'application/json'}
    retry = 3
    success = False
    rsp = ""
    while retry > 0:
      r = requests.post(
        url=url, data=json.dumps(job_config), headers=headers, timeout=60)
      retry -= 1
      rsp = str(r.content)
      if rsp.find('success') != -1:
        success = True
        break
      else:
        time.sleep(60)
    if not success:
      raise Exception('save_job_runtime_config state failed!\r\n' + rsp)

  def get_job_runtime_config(self, task_name, job_name, exec_id):
    if task_name is None or exec_id is None or job_name is None:
      logging.error(
        'get_job_runtime_config [task_name:{0},exec_id:{1},job_name:{2}] error,params error'
        .format(task_name, exec_id, job_name))
      return None
    url = '{0}{1}'.format(self._base_url, URL_GET_JOB_RUNTIME_CONF)
    data = {'taskName': task_name, 'jobName': job_name, 'execId': exec_id}
    r = requests.get(url=url, params=data, timeout=60)
    if r.status_code == requests.codes.ok:
      return r.json()
    else:
      logging.error('gavial api server return code:{0},msg:{1}'.format(
        r.status_code,
        str(r.content)))
      return None

  def save_job_state(self, task_name, schedule_id, job_name, state):
    if task_name is None or schedule_id is None or job_name is None or not isinstance(
        state, dict):
      logging.error(
        'save_job_state [task_name:{0},schedule_id:{1},job_name:{2},state:{3}] error,params error'
        .format(task_name, schedule_id, job_name, state))
      return None
    url = '{0}{1}?taskName={2}&jobName={3}&scheduleId={4}'.format(
      self._base_url, URL_SAVE_JOB_STATE, task_name, job_name,
      schedule_id)
    headers = {'Content-type': 'application/json'}
    r = requests.post(url=url, data=json.dumps(state), headers=headers,
                      timeout=60)
    if str(r.content).find('success') == -1:
      raise Exception('save job state failed!')

  def get_job_state(self, task_name, schedule_id, job_name):
    if task_name is None or schedule_id is None or job_name is None:
      logging.error(
        'save_job_state [task_name:{0},schedule_id:{1},job_name:{2}] error,params error'
        .format(task_name, schedule_id, job_name))
      return None
    url = '{0}{1}'.format(self._base_url, URL_GET_JOB_STATE)
    data = {
      'taskName': task_name,
      'jobName': job_name,
      'scheduleId': schedule_id
    }
    r = requests.get(url=url, params=data)
    if r.status_code == requests.codes.ok:
      return r.json()
    else:
      logging.error('gavial api server return code:{0},msg:{1}'.format(
        r.status_code,
        str(r.content)))
      return None

  def get_job_output_param(self, task_name, job_name, exec_id):
    if task_name is None or exec_id is None or job_name is None:
      logging.error(
        'get_job_output_param [task_name:{0},exec_id:{1},job_name:{2}] error,params error'
        .format(task_name, exec_id, job_name))
      return None
    url = '{0}{1}'.format(self._base_url, URL_GET_JOB_OUTPUT_PARAM)
    data = {'taskName': task_name, 'jobName': job_name, 'execId': exec_id}
    r = requests.get(url=url, params=data, timeout=60)
    if r.status_code == requests.codes.ok:
      return r.json()
    else:
      logging.error('gavial api server return code:{0},msg:{1}'.format(
        r.status_code,
        str(r.content)))
      return None

  def save_job_output_param(self, task_name, job_name, exec_id, params):
    if task_name is None or exec_id is None or job_name is None or not isinstance(
        params, dict):
      logging.error(
        'get_job_output_param [task_name:{0},exec_id:{1},job_name:{2},params:{3}] error,params error'
        .format(task_name, exec_id, job_name, params))
      return None
    url = '{0}{1}?taskName={2}&jobName={3}&execId={4}'.format(
      self._base_url, URL_SAVE_JOB_OUTPUT_PARAM, task_name, job_name,
      exec_id)
    headers = {'Content-type': 'application/json'}
    success = False
    retry = 3
    rsp = ""
    while retry > 0:
      r = requests.post(url=url, data=json.dumps(params), headers=headers,
                        timeout=60)
      retry -= 1
      rsp = str(r.content)
      if rsp.find('success') != -1:
        success = True;
        break
      else:
        time.sleep(60)
    if not success:
      raise Exception('save_job_runtime_config state failed!\r\n' + rsp)

  def get_task_output_params(self, task_name, exec_id):
    if task_name is None or exec_id is None:
      logging.error(
        'get_task_output_param [task_name:{0},exec_id:{1}] error,params error'
        .format(task_name, exec_id))
      return None
    url = '{0}{1}?taskName={2}&execId={3}'.format(
      self._base_url, URL_GET_TASK_OUTPUT_PARAM, task_name, exec_id)
    r = requests.get(url=url, timeout=60)
    if r.status_code == requests.codes.ok:
      return r.json()
    else:
      logging.error(
        'gavial api server return code:{0},error:{1},url:{2}'.format(
          r.status_code, r.content, url))
      return None

  def save_table_info(self,
      task_name,
      ds_name,
      db_name,
      table_name,
      table_desc=""):
    if task_name is None or ds_name is None or db_name is None or table_name is None:
      logging.error(
        'save_table_info [task_name:{0},ds_name:{1},db_name:{2},table_name:{3}] error,params error'
        .format(task_name, ds_name, db_name, table_name))
      return None
    url = '{0}{1}'.format(self._base_url, URL_SAVE_TABLE_INFO)
    data = {
      'taskName': task_name,
      'dsName': ds_name,
      'dbName': db_name,
      'tableName': table_name,
      'tableDesc': table_desc
    }
    r = requests.get(url=url, params=data)
    if str(r.content).find('success') == -1:
      logging.error("data = {0}".format(data))
      logging.error(r.content)
      # raise Exception('save_table_info state failed!')

  def send_message(self, task_name, job_name, exec_id, message):
    if task_name is None or exec_id is None or job_name is None or not isinstance(
        message, dict):
      logging.error(
        'send_message [task_name:{0},exec_id:{1},job_name:{2},message:{3}] error,params error'
        .format(task_name, exec_id, job_name, message))
      return None
    url = '{0}{1}?taskName={2}&jobName={3}&execId={4}'.format(
      self._base_url, URL_SEND_MESSAGE, task_name, job_name, exec_id)
    headers = {'Content-type': 'application/json'}
    r = requests.post(url=url, data=json.dumps(message), headers=headers)
    if str(r.content).find('success') == -1:
      raise Exception('save_job_runtime_config state failed!')
